package com.kc.util;


import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import net.minidev.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * token
 * WebToken制作器
 * 可重复登录
 * 1.0.0
 */
public class JWTutil {

    private final static Logger logger = LoggerFactory.getLogger(JWTutil.class);

    private static final byte[] Secret_key ="askdjhaoisuhklanwjldgirsvrhqzoku".getBytes();

    public static String craateToken(String groud,String visibleId,String ToUID) throws JOSEException{

        //先处理如果有值为空的情况
        if (groud == null && groud.equals("") && visibleId.equals("")&&visibleId==null){
            throw new NullPointerException("其中有值为空");
        }

        //制作载荷
        //web可重复登录，移动端不行
        Map<String ,Object> map = new HashMap<>();

        map.put("groud",groud);

        map.put("visibleId",visibleId);

        map.put("tokenId",ToUID);

        map.put("NowTime",new Date().getTime());

        map.put("EndTime",new Date().getTime()+30*1000*60);


        //制作头
        JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);

        //载荷
        Payload payload = new Payload(JSONObject.toJSONString(map));

        //头和载荷连接
        JWSObject jwsObject = new JWSObject(jwsHeader,payload);

        //建立秘钥
        JWSSigner jwsSigner =null;
        try {
            jwsSigner = new MACSigner(Secret_key);
        } catch (KeyLengthException e) {

            logger.error("这里发生了一个键长度的异常");
        }

        //制作签名
        try {
            jwsObject.sign(jwsSigner);
        } catch (JOSEException e) {
            logger.error("签名发生了异常");
        }

        return jwsObject.serialize();
    }


    //解析token
    public static Boolean Analysis(String token) {
        JWSObject jwsObject = null;
        Payload payload = null;
        JWSVerifier jwsVerifier = null;
        boolean falg = false;

        //解析token
        try {
            jwsObject = JWSObject.parse(token);
        } catch (ParseException e) {
            logger.error("Token parsing failed, please check the server"+e.getMessage());
            return false;
        }

        //获取载荷
        payload = jwsObject.getPayload();

        //建立解锁秘钥
        try {
            jwsVerifier = new MACVerifier(Secret_key);
        } catch (JOSEException e) {
            logger.error("服务器建立解锁秘钥出错查看日志"+e.getMessage());
            return false;
        }

        //效验token是否为有效token
        try {
            falg = jwsObject.verify(jwsVerifier);
        } catch (JOSEException e) {
            logger.error("是一个无效的token"+e.getMessage());
            return false;
        }

        if (falg){
            //从载荷里面获取时间
            Map<String,Object> jsonObject = payload.toJSONObject();
            //效验在载荷里面是否有时间
            if (jsonObject.containsKey("EndTime")){
                Long endTime = Long.valueOf(jsonObject.get("EndTime").toString());
                Long nowTime = new Date().getTime();
                //验证是否过期了token的时间
                if (nowTime<endTime){
                    return true;//有效token
                }else {
                    return false;//无效token
                }
            }else {
                return false;
            }
        }else {
            return false;
        }
    }


    //获取指定的token载荷内容
    //考虑到一些问题以后优化暂时不做
    /**
     *
     * @param token
     * @param content
     * @return
     */
    public static String GetPayload(String token,String content){
//        final Base64.Decoder decoder = Base64.getDecoder();
        JWSObject jwsObject = null;
        Payload payload = null;
        try {
            jwsObject = JWSObject.parse(token);
        } catch (ParseException e) {
            logger.error("Token parsing failed, please check the server");
            return "Token parsing failed";
        }
        payload = jwsObject.getPayload();
        Map<String,Object> jsonObject = payload.toJSONObject();

        return (String) jsonObject.get(content);
    }

}
